package com.es.service.impl;

import com.es.pojo.Items;
import com.es.service.ItemsEsService;
import com.imooc.utils.PagedGridResult;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 顾志杰
 * @date 2020/8/24-14:11
 */
@Service
public class ItemsEsServiceImpl implements ItemsEsService {

    private final ElasticsearchTemplate esTemplate;

    @Autowired
    public ItemsEsServiceImpl(ElasticsearchTemplate esTemplate) {
        this.esTemplate = esTemplate;
    }


    @Override
    public PagedGridResult seathItems(String keywords, String sort, Integer page, Integer pageSize) {
        Pageable pageable = PageRequest.of(page, pageSize);
        SortBuilder sortBuilder = null;
        if("c".equals(sort)){
            sortBuilder = new FieldSortBuilder("sellCounts").order(SortOrder.DESC);
        }else if ("p".equals(sort)){
            sortBuilder = new FieldSortBuilder("price").order(SortOrder.ASC);
        }else{
            /*如果字段是类型是text需要用它的keyword来进行排序*/
            sortBuilder = new FieldSortBuilder("itemName.keyword").order(SortOrder.ASC);
        }
        String preTag = "<font color = 'red'>";
        String postTag = "</font>";
        String itemNameFiled = "itemName";
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery(itemNameFiled, keywords))
                .withHighlightFields(new HighlightBuilder.Field(itemNameFiled)
//                        .preTags(preTag)
//                        .postTags(postTag)
                )
                .withSort(sortBuilder)
                .withPageable(pageable)
                .build();
        AggregatedPage<Items> items = esTemplate.queryForPage(searchQuery, Items.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                List<Items> itemsList = new ArrayList<>();
                SearchHits hits = response.getHits();
                hits.forEach(h -> {
                    HighlightField description = h.getHighlightFields().get(itemNameFiled);
                    String s = description.getFragments()[0].toString();
                    Items items = new Items();
                    items.setItemId((String) h.getSourceAsMap().get("itemId"));
                    items.setImgUrl((String) h.getSourceAsMap().get("imgUrl"));
                    items.setPrice((Integer) h.getSourceAsMap().get("price"));
                    items.setSellCounts((Integer) h.getSourceAsMap().get("sellCounts"));
                    items.setItemName(s);
                    itemsList.add(items);
                });
                    return new AggregatedPageImpl<>((List<T>) itemsList,pageable,response.getHits().getTotalHits());
            }
        });

        PagedGridResult pagedGridResult = new PagedGridResult();
        pagedGridResult.setRows(items.getContent());
        pagedGridResult.setPage(page + 1);
        pagedGridResult.setTotal(items.getTotalPages());
        pagedGridResult.setRecords(items.getTotalElements());
        return pagedGridResult;
    }
}
